
import random
import pygame
import image
from const import *
from peashooter import PeaShooter
from sunflower import SunFlower
from zombiebase import ZombieBase
import data_object
import time
import threading

class Game(object):
    def __init__(self, ds):
        self.ds = ds
        self.back = image.Image(PATH_BACK, 0, (0, 0), GAME_SIZE, 0)
        self.lose = image.Image(PATH_LOSE, 0, (0, 0), GAME_SIZE, 0)
        self.isGameOver = False
        self.plants = []
        self.zombies = []
        self.summons = []
        self.hasPlant = []
        self.gold = 100
        self.goldFont = pygame.font.Font(None, 60)

        self.zombie = 0
        self.zombieFont = pygame.font.Font(None, 60)

        self.zombieGenertateTime = 0

        # 僵尸出现频率
        self.zombieBornCD = 20
        self.timer = None

        # 初始化植物哈希表
        for i in range(GRID_COUNT[0]):
            col = []
            for j in range(GRID_COUNT[1]):
                col.append(0)
            self.hasPlant.append(col)

        # self.timerAction(3, self.increaseDifficulty)
    def timerAction(self, interval, action):
        if self.zombieBornCD <= 3:
            # 取消定时器
            self.timer.cancel()
        self.timer = threading.Timer(interval, self.timerAction, [interval, action])
        self.timer.start()
        action()

    def increaseDifficulty(self): 
        self.zombieBornCD = self.zombieBornCD * 0.9

    def renderFont(self):
        goldText = 'Gold: ' + str(self.gold)
        goldTextSurface = self.goldFont.render(goldText, True, (0, 0, 0))
        self.ds.blit(goldTextSurface, (13, 23))

        goldTextSurface = self.goldFont.render(goldText, True, (255, 255, 255))
        self.ds.blit(goldTextSurface, (10, 20))


        zombieText = 'Score: ' + str(self.zombie)
        zombieTextSurface = self.zombieFont.render(zombieText, True, (0, 0, 0))
        self.ds.blit(zombieTextSurface, (13, 83))

        zombieTextSurface = self.zombieFont.render(zombieText, True, (255, 255, 255))
        self.ds.blit(zombieTextSurface, (10, 80))

    def draw(self):
        self.back.draw(self.ds)
        for plant in self.plants:
            plant.draw(self.ds)
        for summon in self.summons:
            summon.draw(self.ds)
        for zombie in self.zombies:
            zombie.draw(self.ds)
        self.renderFont()

        if self.isGameOver:
            self.lose.draw(self.ds)

    def update(self):
        self.back.update()
        for plant in self.plants:
            plant.update()
            if plant.hasSummon():
                summ = plant.doSummon()
                self.summons.append(summ)
        for summon in self.summons:
            summon.update()
        for zombie in self.zombies:
            zombie.update()

        if time.time() - self.zombieGenertateTime > self.zombieBornCD:
            self.zombieGenertateTime = time.time()
            self.addZombie(ZOMBIE_BORN_X, random.randint(0, GRID_COUNT[1] - 1))

        self.checkSummonVSZombie()
        self.checkZombieVSPlant()

        # 判断游戏是否结束
        for zombie in self.zombies:
            if zombie.getRect().x < GAME_BOUNDARY:
                self.isGameOver = True

        # 解决掉废弃的召唤物
        for summon in self.summons:
            if summon.getRect().x > GAME_SIZE[0] or summon.getRect().y > GAME_SIZE[1]:
                self.summons.remove(summon)
                break

    def checkSummonVSZombie(self):
        for summon in self.summons:
            for zombie in self.zombies:
                # 如果子弹与僵尸发生碰撞
                if summon.isCollide(zombie):
                    # 去战斗
                    self.fight(summon, zombie)
                    # 比较血量
                    if summon.hp <= 0:
                        self.summons.remove(summon)
                    if zombie.hp <= 0:
                        self.zombies.remove(zombie)
                        self.zombie += 1
                    return
    
    def checkZombieVSPlant(self):
        for zombie in self.zombies:
            for plant in self.plants:
                # 如果植物与僵尸发生碰撞
                if zombie.isCollide(plant):
                    # 去战斗
                    self.fight(zombie, plant)
                    # 比较血量
                    if plant.hp <= 0:
                        self.hasPlant[int(plant.x)][int(plant.y)] = 0
                        self.plants.remove(plant)
                        break

    def getIndexByPos(self, pos):
        x = (pos[0] - LEFT_TOP[0]) // GRID_SIZE[0]
        y = (pos[1] - LEFT_TOP[1]) // GRID_SIZE[1]
        return x, y

    def addSunFlower(self, x, y):
        print('------------------')
        self.hasPlant[x][y] = 1
        sf = SunFlower(SUNFLOWER_ID, (x, y))
        self.plants.append(sf)

    def addPeaShooter(self, x, y):
        self.hasPlant[x][y] = 1
        ps = PeaShooter(PEASHOOTER_ID , (x, y))
        self.plants.append(ps)

    def addZombie(self, x, y):
        zombie = ZombieBase(ZOMBIE_ID, (x, y))
        self.zombies.append(zombie)

    def fight(self, a, b):
        while True:
            a.hp -= b.attack
            b.hp -= a.attack
            if a.hp <= 0:
                return True
            if b.hp <= 0:
                return False
        return False

    def checkLoot(self, mousePos):
        for summon in self.summons:
            if not summon.canLoot():
                continue
            rect = summon.getRect()
            if rect.collidepoint(mousePos):
                self.summons.remove(summon)
                self.gold += summon.getPrice()
                return True
        return False

    def checkAddPlant(self, mousePos, objId):
        x, y = self.getIndexByPos(mousePos)

        if x < 0 or x >= GRID_COUNT[0] or y < 0 or y >= GRID_COUNT[1]:
            return

        if self.hasPlant[x][y] == 1:
            return

        objPrice = data_object.data[objId]["PRICE"]
        if self.gold < objPrice:
            return
        self.gold -= objPrice

        print("x:", x, "y:", y)
        print("objId:", objId)
        print("self.hasPlant[x][y]:", self.hasPlant[x][y])

        if objId == SUNFLOWER_ID:
            self.addSunFlower(x, y)
        elif objId == PEASHOOTER_ID:
            self.addPeaShooter(x, y)

    def mouseClickHandler(self, btn):
        if self.isGameOver:
            return

        mousePos = pygame.mouse.get_pos()
        # 若点击的是阳光，则不进行后续操作
        if self.checkLoot(mousePos): return
        if btn == 1:
            # 左键点击 种下向日葵
            self.checkAddPlant(mousePos, SUNFLOWER_ID)
        if btn == 3:
            # 右键点击 种下豌豆射手
            self.checkAddPlant(mousePos, PEASHOOTER_ID)
        if btn == 2:
            # 滚轮点击 种满豌豆射手
            for i in range(GRID_COUNT[0]):
                for j in range(GRID_COUNT[1]):
                    if self.hasPlant[i][j] == 0:
                        self.hasPlant[i][j] = 1
                        self.addPeaShooter(i, j)

    